Categories
Node.js Tips

Node.js Tips — Download Files, Async Test, Socket.io Custom

Spread the love

As with any kind of app, there are difficult issues to solve when we write Node apps. In this article, we’ll look at some solutions to common problems that we might encounter when writing Node apps.

Log Inside page.evaluate with Puppeteer

We can log output when page.evaluate is run by listening to the console event.

For instance, we can write:

const page = await browser.newPage();
page.on('console', consoleObj => console.log(consoleObj.text()));

We call browser.newPage to create a new page object.

Then we listen to the console event with it.

It takes a callback, which we can convert to text with the text method.

Testing Asynchronous Function with Mocha

We can run async functions with Mocha tests to test them.

For instance, we can write:

it('should do something', async function() {
  this.timeout(40000);
  const result = await someFunction();
  assert.isBelow(result, 3);
});

We call this.timeout to set the timeout before the test times out.

Then we use await to run our async function, which returns a promise.

Finally, we get the result and use assert to check it.

Acknowledgment for socket.io Custom Event

We can listen to events after a connection is established.

On the server-side, we can listen to the connection event to see if a connection is established.

Once it is, then we emit an event to acknowledge the connection is made.

Likewise, we can do the same on the client-side.

For instance, in our server-side code, we write:

io.sockets.on('connection', (sock) => {
   sock.emit('connected', {
     connected: 'yes'
   });

   sock.on('message', (data, callback) => {
     console.log('received', data);
     const responseData = {
       hello: 'world'
     };

     callback(responseData);
   });
 });

We listen to the connection event to listen to connections.

Then we emit the connected event to acknowledge the connection.

We also listen to the message event which takes data and a callback, which we call to send data back to the client.

The on the client-side, we write:

const socket = io.connect('http://localhost:3000');
socket.on('error', (err) => {
  console.error(err);
});

socket.on('connected', (data) => {
  console.log('connected', data);
  socket.emit('message', {
    payload: 'hello'
  }, (responseData) => {
    console.log(responseData);
  });
});

We connect to the server with io.connect .

And we listen to the error even which runs a callback if there’s an error.

We also listen to the connected event for any data that’s sent.

And we emit a message event with some data and a callback which the server calls to get the data we passed into the callback function in the server-side code.

responseData is the responseData passed into callback in the server-side code.

Download Large File with Node.js while Avoiding High Memory Consumption

We can make an HTTP request with the http module.

Then we listen to the response event, which has the downloaded file’s content.

We create a write stream with the file path.

Then we listen to the data event emitted on the response object to get the chunks of data.

We also listen to the end event emitted from response so that we can stop writing to the stream.

For example, we can write:

const http = require('http');
const fs = require('fs');

const download = (url, dest, cb) => {
  const file = fs.createWriteStream(dest);
  const request = http.get(url, (response) => {
    response.pipe(file);
    file.on('finish', () => {
      file.close(cb);
    });
  }).on('error', (err) => {
    fs.unlink(dest);
    if (cb) cb(err.message);
  });
};

We created a write stream with fs.createWriteStream .

Then we make our request with the http.get method.

We call response.pipe to pipe the response to our write stream, which writes it to the file.

We listen to the finish event and close the write stream in the callback.

If there’s an error, we delete what’s written so far with unlink .

We listen to the error event to watch for errors.

cb is a callback that we call to deliver the results.

Since the data is obtained in chunks, memory usage shouldn’t be an issue.

Conclusion

We can download a file and write it to disk with a write stream. We can log the output with Puppeteer. Mocha can run async functions in tests. We can send events to acknowledge the emission of custom events.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *